package com.coszero.utils.utils

import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.math.RoundingMode
import java.text.DecimalFormat
import java.util.regex.Matcher
import java.util.regex.Pattern


/**
 * @author xmqian
 * @version 5
 * @date 2018/5/29
 * @desc 字符串操作类
 *
 *
 * 将格式化字符串的方法使用format开头，比如金钱保留两位小数 formatMoney()
 * 判断字符串是否符合标准的都使用 is开头，比如是否是手机号 isPhoneNumber()
 * 类型转换都是用to开头，传入的类型作为入参传入就行，比如字符数组转字符串 toString(String[] strArray);
 */
object StringUtils {
    // <editor-fold desc="格式化字符串" defaultstate="collapsed">
    // <editor-fold desc="格式化小数位数" defaultstate="collapsed">
    /**
     * 格式化小数位数
     * 由于金钱比较敏感，这里不能进行四舍五入,保持直接截取
     * 位数
     *
     * @param value 需要格式化的小数
     * @param isRoundingMode 是否进行舍入模式 true:进行四舍五入 false:直接截取多余的数字
     * @param decimalDigits 需要保留的小数位数
     * @param isAddZero 小数位数不足是否补0 true:补 false:不补
     * @return 格式化的字符串
     */
    fun formatDecimalDigits(
        value: Double?,
        isRoundingMode: Boolean,
        decimalDigits: Int,
        isAddZero: Boolean
    ): String {
        val builder: StringBuilder = StringBuilder("###.")
        for (i in 0 until decimalDigits) {
            //使用0的时候，如果位数不足会补0，使用#不会补足位数
            builder.append(if (isAddZero) "0" else "#")
        }
        val df: DecimalFormat = DecimalFormat(builder.toString())
        if (!isRoundingMode) {
            df.setRoundingMode(RoundingMode.FLOOR)
        }
        return df.format(value)
    }


    /**
     * @param value
     * @param isRoundingMode
     * @param decimalDigits
     * @return
     */
    @JvmStatic
    @Deprecated("仅保留固定的 金钱格式化，和单小数，双小数的格式化方法，其他均使用最多参数的方法")
    fun formatDecimalDigits(value: Double?, isRoundingMode: Boolean, decimalDigits: Int): String {
        return formatDecimalDigits(value, isRoundingMode, decimalDigits, true)
    }

    /**
     * @param value value
     * @param decimalDigits 位数
     * @return 格式化后值
     */
    fun formatDecimalDigits(value: Double?, decimalDigits: Int): String {
        return formatDecimalDigits(value, false, decimalDigits, true)
    }

    /**
     * @param money 格式化金钱，保留两位小数，不进行四舍五入
     * @return 金钱格式化, 两位小数，整数会补两位0，不进行四舍五入
     */
    @JvmStatic
    fun formatMoney(money: String): String {
        return formatDecimalDigits(money.toDouble(), false, 2, true)
    }

    /**
     * 格式化小数为一位小数
     *
     * @param value 数值
     * @return 一位小数数值，不进行四舍五入,整数不补0
     */
    fun formatSingleDecimal(value: Double): String {
        return formatDecimalDigits(value, false, 1, false)
    }

    /**
     * 格式化小数为两位位小数
     *
     * @param value 数值
     * @return 两位位小数数值，不进行四舍五入,整数不补0
     */
    fun formatDoubleDecimal(value: Double): String {
        return formatDecimalDigits(value, false, 2, false)
    }

    //</editor-fold>
    /**
     * @return 获取最小两位的数字
     */
    fun formatMineTwoNumber(i: Int): String {
        if (i < 10) {
            return "0" + i
        }
        return "" + i
    }

    /**
     * 格式化手机号，中间4-7位号码隐藏
     *
     * @param phoneNum
     * @return
     */
    fun formatPhone(phoneNum: String): String {
        return phoneNum.substring(0, 3).intern() + "****" + phoneNum.substring(7, 11).intern()
    }

    /**
     * 截取字符串
     *
     * @param data 源数据
     * @param charAt 截取的字符
     * @return
     */
    fun formatSplitString(data: String?, charAt: String): Array<String>? {
        if (data != null && data.contains(charAt)) {
            return data.split(charAt.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        }
        return null
    }

    //</editor-fold>
    // <editor-fold desc="判断字符串是否符合条件" defaultstate="collapsed">
    /**
     * 验证18位身份证
     *
     * @param input The input.
     * @return `true`: yes<br></br>`false`: no
     */
    fun isIDCard(input: CharSequence): Boolean {
        val regExp: String =
            "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9Xx])$"
        val p: Pattern = Pattern.compile(regExp)
        val m: Matcher = p.matcher(input)
        return m.matches()
    }

    /**
     * 密码是否是字母和数字的组合
     *
     * @param pwd
     * @return
     */
    fun isPwd(pwd: String): Boolean {
        val regex: String = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$"
        return pwd.matches(regex.toRegex())
    }

    /**
     * 是否是标准的手机号码
     *
     * @param str
     * @return
     */
    fun isPhone(str: String): Boolean {
        val regExp: String = "^((13[0-9])|(15[^4])|(18[0-9])|(17[0-8])|(147))\\d{8}$"
        val p: Pattern = Pattern.compile(regExp)
        val m: Matcher = p.matcher(str)
        return m.matches()
    }

    /**
     * 判断给定字符串是否空白串。
     * 空白串是指由空格、制表符、回车符、换行符组成的字符串
     * 若输入字符串为null或空字符串，返回true
     *
     * @param input
     * @return boolean
     */
    @JvmStatic
    fun isEmpty(input: String?): Boolean {
        if (input == null || "" == input || "null" == input) return true

        for (i in 0 until input.length) {
            val c: Char = input.get(i)
            if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
                return false
            }
        }
        return true
    }

    /**
     * 判断是不是一个合法的电子邮件地址
     *
     * @param email
     * @return
     */
    fun isEmail(email: String?): Boolean {
        val emailer: Pattern = Pattern
            .compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*")
        if (email == null || email.trim { it <= ' ' }.length == 0) return false
        return emailer.matcher(email).matches()
    }

    //</editor-fold>
    // <editor-fold desc="类型转换" defaultstate="collapsed">
    /**
     * 字符串转整数
     *
     * @param str
     * @param defValue
     * @return
     */
    @Deprecated("Integer.valueOf(str)")
    fun toInt(str: String, defValue: Int): Int {
        try {
            return str.toInt()
        } catch (e: Exception) {
        }
        return defValue
    }

    /**
     * 把数组转换成字符拼接的字符串
     * 默认使用“,”进行拼接
     *
     * @param ss 数组
     * @param splitChar 传入分割的字符
     * @return
     */
    fun toString(ss: Array<String?>?, splitChar: String?): String {
        val s: StringBuffer = StringBuffer()
        if (null != ss) {
            for (i in 0 until ss.size - 1) {
                s //                        .append("'")
                    .append(ss.get(i)) //                        .append("'")
                    .append(splitChar)
            }
            if (ss.size > 0) {
                s.append("'").append(ss.get(ss.size - 1)).append("'")
            }
        }
        return s.toString()
    }

    /**
     * 把数组转换成字符拼接的字符串
     * 默认使用“,”进行拼接
     *
     * @param ss 数组
     * @return
     */
    fun arrayToString(ss: Array<String?>?): String {
        return toString(ss, ",")
    }

    /**
     * 对象转整数
     *
     * @param obj
     * @return 转换异常返回 0
     */
    @Deprecated("系统的方法更方便")
    fun toInt(obj: Any?): Int {
        if (obj == null) return 0
        return toInt(obj.toString(), 0)
    }

    /**
     * 对象转整数
     *
     * @param obj
     * @return 转换异常返回 0
     */
    @Deprecated("")
    fun toLong(obj: String): Long {
        try {
            return obj.toLong()
        } catch (e: Exception) {
        }
        return 0
    }

    /**
     * 字符串转布尔值
     *
     * @param b
     * @return 转换异常返回 false
     */
    @Deprecated("")
    fun toBool(b: String): Boolean {
        try {
            return b.toBoolean()
        } catch (e: Exception) {
        }
        return false
    }


    /**
     * 将一个InputStream流转换成字符串
     *
     * @param is
     * @return
     */
    fun toConvertString(`is`: InputStream?): String {
        var `is`: InputStream? = `is`
        val res: StringBuffer = StringBuffer()
        val isr: InputStreamReader = InputStreamReader(`is`)
        var read: BufferedReader? = BufferedReader(isr)
        try {
            var line: String?
            line = read!!.readLine()
            while (line != null) {
                res.append(line)
                line = read.readLine()
            }
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                if (null != isr) {
                    isr.close()
                    isr.close()
                }
                if (null != read) {
                    read.close()
                    read = null
                }
                if (null != `is`) {
                    `is`.close()
                    `is` = null
                }
            } catch (e: IOException) {
            }
        }
        return res.toString()
    }

    /**
     * 截取字符串
     *
     * @param data 源数据
     * @param charAt 截取的字符
     * @return
     */
    fun splitString(data: String?, charAt: String): Array<String>? {
        if (data != null && data.contains(charAt)) {
            return data.split(charAt.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        }
        return null
    }

    /**
     * 判断字符串是不是数字
     *
     * @param str
     * @return
     */
    fun isNumeric(str: String): Boolean {
        if (str.startsWith("0")) {
            return false
        }

        val pattern: Pattern = Pattern.compile("[0-9]*")
        val isNum: Matcher = pattern.matcher(str)
        return isNum.matches()
    }

    /**
     * null转为长度为0的字符串
     *
     * @param s 待转字符串
     * @return s为null转为长度为0字符串，否则不改变
     */
    fun null2Length0(s: String?): String {
        return if (s == null) "" else s
    }

    /**
     * 格式化手机号，中间4-7位号码隐藏
     *
     * @param phoneNum
     * @return
     */
    fun getPhoneFormat(phoneNum: String): String {
        return phoneNum.substring(0, 3).intern() + "****" + phoneNum.substring(7, 11).intern()
    }

    /**
     * 把数组转换成字符拼接的字符串
     * 默认使用“,”进行拼接
     *
     * @param ss 数组
     * @param splitChar 传入分割的字符
     * @return
     */
    fun arrayToString(ss: Array<String?>?, splitChar: String?): String {
        val s: StringBuffer = StringBuffer()
        if (null != ss) {
            for (i in 0 until ss.size - 1) {
                s //                        .append("'")
                    .append(ss.get(i)) //                        .append("'")
                    .append(splitChar)
            }
            if (ss.size > 0) {
                s.append("'").append(ss.get(ss.size - 1)).append("'")
            }
        }
        return s.toString()
    }

    /**
     * @return 获取最小两位的数字
     */
    fun getMineTwoNumber(i: Int): String {
        if (i < 10) {
            return "0" + i
        }
        return "" + i
    }

    /**
     * @return 获取最小两位的数字
     */
    fun getMineThreeNumber(i: Int): String {
        if (i < 10) {
            return "00" + i
        } else if (i < 100) {
            return "0" + i
        }
        return "" + i
    }

    /**
     * 将数组字符串拼接为字符串
     *
     * @return 返回数据内容字符串
     */
    fun getDataArrayStringBuilder(dataHexArray: Array<String?>?): String {
        val dataStr: StringBuilder = StringBuilder()
        if (dataHexArray != null && dataHexArray.size > 0) {
            for (i in dataHexArray.indices) {
                dataStr.append(dataHexArray.get(i))
            }
        }
        return dataStr.toString()
    }
}
